//测试GGX的几何函数的像素着色器

#define PI 3.1415926

//顶点着色器输出
struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float3 Normal : NORMAL;
	float2 TexCoord : TEXCOORD0;
	float3 WorldPosition : TEXCOORD1;
};

TextureCube skyboxCubeMap : register( t9 );
SamplerState ourSampler : register( s5 );

cbuffer SceneData : register( b7 )
{
	matrix View;
	matrix Projection;
	float4 lightDir;
	float4 eyePosition;
	float4 TestValue;
}

float chi(float v)
{
	return v > 0 ? 1 : 0;
}
//GGX的几何函数
//a：粗糙度
//w：要检查的方向（入射或出射）
//m：微面元的法线
//n：宏观表面的法线
float GGX_Geometry(float a, float3 w, float3 m, float3 n)
{
	float w_d_m = dot(w, m);
	float w_d_n = dot(w, n);
	float tanTheta2 = (1.0 - pow(w_d_n, 2)) / pow(w_d_n, 2);
	return chi(w_d_m / w_d_n) * 2 /
		(1 + sqrt(1 + a * a * tanTheta2));
}

float4 Main(VS_OUTPUT input) : SV_Target
{
	//测试的粗糙度
	float TestRoughness = TestValue;

	//视线方向
	float3 V = normalize(eyePosition.xyz - input.WorldPosition);

	//光线方向
	float3 L = normalize(lightDir);

	//半向量
	float3 HalfVector = normalize(L + V);

	//检查方向为半向量的微面元在出射方向上的遮挡
	float Go = GGX_Geometry(TestRoughness, V, HalfVector, normalize(input.Normal));
	//检查方向为半向量的微面元在入射方向上的遮挡
	float Gi = GGX_Geometry(TestRoughness, L, HalfVector, normalize(input.Normal));

	//综合的值
	float G = Go * Gi;

	//输出以可视化
	return float4(G, G, G, 1);
}
